package com.hronline;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import yaochangwei.pulltorefreshlistview.widget.RefreshableListView;
import yaochangwei.pulltorefreshlistview.widget.RefreshableListView.OnUpdateTask;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

import com.adapter.EmployeesAdapter;
import com.delegate.ManagerEmployeesDelegate;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.models.Employees;
import com.models.Item;
import com.models.SectionItem;
import com.models.Status;
import com.parser.ManagerParser;

public class EmployeesActivity extends Fragment {
	
	private ArrayList<Item> arrData = new ArrayList<Item>();
	private ArrayList<Employees>arrEmployees = new ArrayList<Employees>();
	private EmployeesAdapter adapter;
	Map<String, ArrayList<Employees>> employeeMap	=	new HashMap<String, ArrayList<Employees>>();
	TreeMap<String, ArrayList<Employees>> treeEmployeeMap;
	RefreshableListView empListView;
	
	private ProgressDialog loadingDialog;
	private LinearLayout sideIndexLayout;
	
	private Context context;
	private ManagerEmployeesDelegate delegate;

	public EmployeesActivity (Context context, ManagerEmployeesDelegate delegate){
		
		this.context	=	context;
		this.delegate	=	delegate;
		
		/* set up loading dialog */
		loadingDialog	=	new ProgressDialog(this.context);
		this.loadingDialog.setMessage(Constant.LOADING_STRING);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View fragmentView = inflater.inflate(R.layout.activity_employees, container, false);
		
		/* set up view */
		createNavigationBar(fragmentView);
		setUpViewControl(fragmentView);
		
		if(this.arrEmployees.size() == 0){
			getAllEmployees();
		}
		
		return fragmentView;
	}
	
	/*
	 * INIT VIEW
	 * This section is used to set up view
	 * */
	
	/* this method is used to set up navigation bar */
	private void createNavigationBar(View view){
		ImageButton imbOrganization	=	(ImageButton)view.findViewById(R.id.btnOrganization);
		imbOrganization.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				didClickOrganizationButton();
			}
		});
	}
	
	/* this method is used to get control and handle on this view */
	private void setUpViewControl(final View view){
		
		/* get the search control */
		final EditText edtSearch	=	(EditText)view.findViewById(R.id.edtSearch);
		
		final ImageButton btnCloseSearch	=	(ImageButton)view.findViewById(R.id.btnCloseSearch);
		btnCloseSearch.setVisibility(View.INVISIBLE);
		btnCloseSearch.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				edtSearch.setText("");
			}
		});
		
		
		
		edtSearch.addTextChangedListener(new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				// TODO Auto-generated method stub
				if(edtSearch.getText().length() > 0){
					btnCloseSearch.setVisibility(View.VISIBLE);
				}
				else{
					btnCloseSearch.setVisibility(View.INVISIBLE);
				}
				searchEmployee(edtSearch.getText().toString());
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				
			}
		});
		
		/* get list view */
		this.adapter	=	new EmployeesAdapter(this.context, arrData);
		empListView	=	(RefreshableListView)view.findViewById(R.id.employeesListView);
		empListView.setAdapter(this.adapter);
		empListView.setFastScrollEnabled(true);
		empListView.setOnUpdateTask(new OnUpdateTask() {
			
			@Override
			public void updateUI() {
				// TODO Auto-generated method stub
				
				getAllEmployees();
			}
			
			@Override
			public void updateBackground() {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onUpdateStart() {
				// TODO Auto-generated method stub
				
			}
		});
		empListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// TODO Auto-generated method stub
				Item item	=	arrData.get(arg2 - 1);
				
				if(!item.isSection()){

					InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
					
					/* open the employee detail view */
					Employees empItem	=	(Employees)item;
					openEmployeeDetailPage(empItem);
				}
			}
		});
		
		
		sideIndexLayout	=	(LinearLayout)view.findViewById(R.id.sideIndex);
	}
	
	
	/*
	 * SELECTOR
	 * This section is used to create selector
	 * */
	
	/* this method is used to create selector */
	private void didClickOrganizationButton(){
		
	}
	
	/* this method is used to open employee detail */
	private void openEmployeeDetailPage(Employees empItem){
		String empName	=	String.format("%s %s", empItem.getForeName(), empItem.getSurName());
		
		delegate.openEmployeeDetail(empItem.getEmpId(), empName);
	}
	
	/* this method is used to display the side index */
	private void displayTheSideIndex(String key, final int position){

			TextView textView	=	new TextView(this.context);
			textView.setText(key);
			textView.setTextColor(Color.DKGRAY);
			textView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
			textView.setTextSize(11);
			
			textView.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					Log.i("duylept", String.format("%d", position));
					empListView.setSelectionFromTop(position, 0);
				}
			});
			
			sideIndexLayout.addView(textView);
	}
	
	/* this method is used to search employee name */
	private void searchEmployee(String searchText){
		
		this.arrData.clear();
		this.adapter.refreshData();
		this.adapter.notifyDataSetChanged();
		
		if(searchText.length() > 0){
			sideIndexLayout.setVisibility(View.INVISIBLE);
		
			for (Employees empItem : this.arrEmployees) {
				
				String fullName	=	String.format("%s %s", empItem.surName, empItem.foreName);
				if(fullName.toLowerCase().contains(searchText.toLowerCase())){
					this.arrData.add(empItem);
				}
			}
		}
		else{ //display all employees
			sideIndexLayout.setVisibility(View.VISIBLE);
			prepareDataToDisplay();
		}
		
		this.adapter.setArrayData(this.arrData);
		this.adapter.notifyDataSetChanged();
	}
	
	/* this method is used to filter data into the section */
	private void seperateDataIntoSection(){
		for(int index = 0; index < this.arrEmployees.size(); index++){
			
			/* Get the data to seperate into section */
			Employees empItem	=	this.arrEmployees.get(index);
			String firstChar	=	empItem.getSurName().substring(0, 1);
			
			if(employeeMap.get(firstChar) != null){
				
				ArrayList<Employees> arrEmployeesTemp	=	employeeMap.get(firstChar);
				arrEmployeesTemp.add(empItem);
				employeeMap.put(firstChar, arrEmployeesTemp);
			}
			else{
				
				ArrayList<Employees> arrEmpTemp	=	new ArrayList<Employees>();
				arrEmpTemp.add(empItem);
				employeeMap.put(firstChar, arrEmpTemp);
			}
		}
	}
	
	/* this method is used to prepare data to setup to list view */
	private void prepareDataToDisplay(){
		
		/* remove the old treeEmployeeMap */
		treeEmployeeMap	=	null;
		treeEmployeeMap	=	new TreeMap<String, ArrayList<Employees>>(employeeMap);
		
		String sections	=	"";
		
		for (String key : treeEmployeeMap.keySet()) {
			
			sections	=	String.format("%s%s", sections, key);
			
			this.arrData.add(new SectionItem(key));
			displayTheSideIndex(key, this.arrData.size());
			this.arrData.addAll(employeeMap.get(key));
		}
	}
	
	/* CALL API 
	 * This section is used to call api and handle api
	 *  */
	
	/* this method is used to create connection to call api */
	private void getAllEmployees(){
		
		this.loadingDialog.show();
		
		String url	=	String.format("%sEmployee/GetEmployees?AuthorisationToken=%s", Constant.SERVER_ADDRESS, Constant.AUTHORIZED_TOKEN);
		
		AsyncHttpClient client	=	new AsyncHttpClient();
		client.get(url, new AsyncHttpResponseHandler(){
			
			@Override
			public void onSuccess(String content) {
				// TODO Auto-generated method stub
				super.onSuccess(content);
				handleGetEmployeesSuccess(content);
			}
			
			@Override
			public void onFailure(Throwable error, String content) {
				// TODO Auto-generated method stub
				super.onFailure(error, content);
				handleGetConnectionFail();
			}
			
		});
		
	}
	
	/* this method is used to handle when get employee success */
	@SuppressWarnings("unchecked")
	private void handleGetEmployeesSuccess(String result){
		
		ArrayList<Object> arrResult	=	ManagerParser.parseAllEmployees(result);
		
		/* get status object */
		Status statusItem	=	(Status)arrResult.get(0);
		if(!isStatusError(statusItem, "getAllEmployees")){
			
			this.arrEmployees	=	(ArrayList<Employees>)arrResult.get(1);
			Collections.sort(this.arrEmployees, new Comparator<Employees>() {

				@Override
				public int compare(Employees lhs, Employees rhs) {
					// TODO Auto-generated method stub
					return lhs.getSurName().compareTo(rhs.getSurName());
				}
			});
			
			seperateDataIntoSection();
			prepareDataToDisplay();
			adapter.notifyDataSetChanged(); //reload data
			
			this.loadingDialog.dismiss();
		}
		
	}
	
	/* this method is used to handle when get connection fail */
	private void handleGetConnectionFail(){
		
		this.loadingDialog.dismiss();
		Constant.showErrorMessage(this.context, Constant.CANNOT_CONNECT_SERVER);
	}
	
	/* this method is used to check status of message return form server */
	private boolean isStatusError(Status statusItem, String apiCalling){
		
		/* dismiss the loading dialog */
		loadingDialog.dismiss();
		
		if(statusItem.statusCode >= Constant.IVALID_AUTHORIZED_TOKEN){
			String message	=	String.format("%s - API %s", statusItem.getStatusText(), apiCalling);
			
			AlertDialog.Builder builder	=	new AlertDialog.Builder(this.context);
			builder.setMessage(message);
			builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					dialog.dismiss();
					delegate.openLoginPage();
				}
			});
			
			builder.show();
			
			return true;
		}
		
		return false;
	}

}
